﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DoddleReport;
using System.IO;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.ComponentModel;
using System.Collections.Specialized;

namespace FrameworkLib.Utilities.Export
{
    public static class Exporter
    {
        public static bool ToPDF<T>(this IEnumerable<T> list, string filename, out string errorMessage, string[] columnsToHide = null)
        {
            bool retValue = false;

            try
            {
                var report = new Report(list.ToReportSource());

                if (columnsToHide != null)
                {
                    foreach (string s in columnsToHide)
                    {
                        report.DataFields[s].Hidden = true;
                    }
                }

                DoddleReport.iTextSharp.PdfReportWriter ew = new DoddleReport.iTextSharp.PdfReportWriter();
                using (FileStream fs = new FileStream(filename, FileMode.Create))
                {
                    ew.WriteReport(report, fs);
                }

                retValue = true;
                errorMessage = string.Empty;
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
            }

            return retValue;
        }

        public static bool ToExcel<T>(this IEnumerable<T> list, string filename, out string errorMessage, string[] columnsToHide = null)
        {
            bool retValue = false;

            try
            {
                var report = new Report(list.ToReportSource());

                if (columnsToHide != null)
                {
                    foreach (string s in columnsToHide)
                    {
                        report.DataFields[s].Hidden = true;
                    }
                }
                
                DoddleReport.Writers.ExcelReportWriter ew = new DoddleReport.Writers.ExcelReportWriter();
                using (FileStream fs = new FileStream(filename, FileMode.Create))
                {
                    ew.WriteReport(report, fs);
                }

                retValue = true;
                errorMessage = string.Empty;
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
            }

            return retValue;
        }

        private static string GetAttributeDisplayName(PropertyInfo property)
        {
            var atts = property.GetCustomAttributes(
                typeof(DisplayNameAttribute), true);
            if (atts.Length == 0)
                return null;
            return (atts[0] as DisplayNameAttribute).DisplayName;
        }

        private static string GetMetaDisplayName(PropertyInfo property)
        {
            var atts = property.DeclaringType.GetCustomAttributes(typeof(MetadataTypeAttribute), true);
            if (atts.Length == 0)
                return null;

            var metaAttr = atts[0] as MetadataTypeAttribute;
            var metaProperty = metaAttr.MetadataClassType.GetProperty(property.Name);
            if (metaProperty == null)
                return null;
            else
            {
                var atts2 = metaProperty.GetCustomAttributes(typeof(DisplayAttribute), true);
                if (atts2 != null)
                {
                    return (atts2[0] as DisplayAttribute).Name;
                }
            }

            return GetAttributeDisplayName(metaProperty);
        }

        private static DisplayAttribute GetMetaDisplayAttribute(PropertyInfo property)
        {
            DisplayAttribute retValue = null;

            var atts = property.DeclaringType.GetCustomAttributes(typeof(MetadataTypeAttribute), true);
            if (atts.Length == 0)
                return null;

            var metaAttr = atts[0] as MetadataTypeAttribute;
            var metaProperty = metaAttr.MetadataClassType.GetProperty(property.Name);
            if (metaProperty == null)
                return null;
            else
            {
                var atts2 = metaProperty.GetCustomAttributes(typeof(DisplayAttribute), true);
                if (atts2 != null)
                {
                    retValue = (atts2[0] as DisplayAttribute);
                }
            }

            return retValue;
        }

        public static Dictionary<string, int> GetOrderedProperties<T>(this IEnumerable<T> list)
        {
            Dictionary<string, int> retValue = null;

            Type itemType = typeof(T);

            foreach (PropertyInfo pi in itemType.GetProperties())
            {
                DisplayAttribute da = GetMetaDisplayAttribute(pi);

                if (da != null)
                {
                    if (retValue == null) retValue = new Dictionary<string, int>();

                    retValue.Add(pi.Name, da.Order);
                }
            }

            return retValue;
        }

        public static void CreateExcelDocument<T>(this IEnumerable<T> data, string filename)
        {
            //ApplicationClass ExcelApp = new ApplicationClass();

            //Dictionary<string, int> valori = data.GetOrderedProperties();


            //Workbook m_workbook = ExcelApp.Application.Workbooks.Add(Type.Missing);
            //Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)m_workbook.Sheets[1];

            //// storing headers...
            //int index = 1;
            //foreach (var field in valori.OrderBy(kv => kv.Value).Select(kv => kv.Key))
            //{
            //    string s = field.ToString();
            //    worksheet.Cells[1, index++] = s;
            //}

            //// storing values...
            //int row = 0;
            //int col = 0;
            //foreach (T m in data)
            //{
            //    foreach (var field in valori.OrderBy(kv => kv.Value).Select(kv => kv.Key))
            //    {
            //        PropertyInfo pi = m.GetType().GetProperty(field);

            //        string s = (pi.GetValue(m, null) == null ? string.Empty : pi.GetValue(m, null).ToString());
            //        worksheet.Cells[row + 2, col + 1] = s;

            //        col++;
            //    }

            //    row++;
            //    col = 0;
            //}

            //ExcelApp.ActiveWorkbook.SaveCopyAs(filename);

            //ExcelApp.ActiveWorkbook.Saved = true;

            //ExcelApp.Quit();
        }
    }
}
